package com.sujeet.learning.threads;

import java.util.List;
import java.util.ArrayList;

import java.io.File;

/**
 * This demonstrates composite pattern and also tree fill up and usage of
 * java.io.File
 * 
 * @author sujeet
 * 
 */
interface Component {
	public String getName();
}

class CompositeNode implements Component {

	private List<Component> childNodes = new ArrayList<Component>();
	private String compositeName;

	public String getCompositeName() {
		return compositeName;
	}

	public void setCompositeName(String compositeName) {
		this.compositeName = compositeName;
	}

	@Override
	public String getName() {
		StringBuilder sb = new StringBuilder();
		sb.append("\n");
		sb.append(getCompositeName());
		sb.append("\n");
		for (Component component : childNodes) {
			sb.append(component.getName());
			sb.append("\n");
		}
		return sb.toString();
	}

	public void add(Component node) {
		childNodes.add(node);
	}

	public void remove(Component node) {
		childNodes.remove(node);
	}

	@Override
	public boolean equals(Object that) {
		if (that == null)
			return false;
		if (this == that)
			return true;
		if (that instanceof CompositeNode) {
			CompositeNode thatNode = (CompositeNode) that;
			return thatNode.childNodes.equals(this.childNodes);
		}
		return false;
	}
}

class Node implements Component {
	public String name;

	Node(String name) {
		this.name = name;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public boolean equals(Object that) {
		if (that == null)
			return false;
		if (this == that)
			return true;
		if (that instanceof Node) {
			Node thatNode = (Node) that;
			return (thatNode.name.equals(this.name));
		}
		return false;
	}

}

public class Traverse {

	public static void main(String[] args) {
		File f = new File("/home/sujeet/Music");
		System.out.println("Is it readable?\nAns. " + f.canRead());
		System.out.println("Is it a directory?\nAns. " + f.isDirectory());
		Component c = fill(f);
		System.out.println("\ncontents\n");
		System.out.println(c.getName());
	}

	private static Component fill(File f) {
		Component c = null;
		if (f.isDirectory()) {
			File[] children = f.listFiles();
			CompositeNode cn = new CompositeNode();			
			for (File child : children) {
				//System.out.println(child.getName());
				cn.setCompositeName(f.getName());
				cn.add(fill(child));				
			}
			c = cn;
		} else {
			c = new Node(f.getName());
		}
		return c;
	}

}
